package Gui; 
 
import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.util.Vector; 
 
import javax.swing.AbstractAction; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane;
import javax.swing.JSlider;

import static javax.swing.ScrollPaneConstants.*;
 
import tools.OpenSaveVertices; 
 
import Triangulation.minimalityMetrics.AdjacentBaseToHeightRatioMetric; 
import Triangulation.minimalityMetrics.LongestBaseToHeightRatioMetric;
import Triangulation.minimalityMetrics.ShortestEdgesMetric; 
import Triangulation.oldMinimalityMetrics.OldBaseToHeightRatioMetric; 
import Triangulation.oldMinimalityMetrics.OldShortestEdgesMetric; 
import datatypes.Vertex;


 
public class MainWindow extends JFrame 
{ 
    private static final long serialVersionUID = 3940935757890529911L; 
 
//    public UserDrawWindow userInputWindow; 
    private TriangleDisplay triangulationWindow; 
    private JButton clearButton, randomGenerateButton, loadButton, saveButton; 
    private JPanel windowNorth, windowCenter; 
    private JComboBox triangulatersComboBox; 
    private Vector<Triangulation.EdgeGenerator> triangulaters; 
    private int activeTriangulater = 0; 
    private RandomizePointsDialog randPointsDialog;
    private SaveVerticesDialog saveVertsDialog;
    private LoadVerticesDialog loadVertsDialog;
    private ExtraInfoPanel infoPanel;
    private Boolean showExtraInfo = true;
    
    public static void main(String args[]) 
    { 
        new MainWindow("Optimal triangulation (Click to add points)", 900, 512); 
    } 
 
    public MainWindow(String title, int width, int height) 
    { 
        super(title); 
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        setSize(width, height); 
 
        getContentPane().setLayout(new BorderLayout()); 
 
        triangulaters = new Vector<Triangulation.EdgeGenerator>(); 
 
        windowNorth = new JPanel(); 
        windowNorth.setLayout(new BoxLayout(windowNorth, BoxLayout.X_AXIS)); 
        windowNorth.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 
        windowCenter = new JPanel(); 
        windowCenter.setBorder(BorderFactory.createEmptyBorder(0, 2, 2, 2)); 
        windowCenter.setLayout(new BoxLayout(windowCenter, BoxLayout.X_AXIS)); 
 
        triangulationWindow = new TriangleDisplay(this); 
        JScrollPane scrollPane = new JScrollPane(triangulationWindow);
        //scrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_ALWAYS);
        //scrollPane.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS);
        
        scrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
        windowCenter.add(scrollPane); 
 
        clearButton = new JButton(new AbstractAction("Clear") 
        { 
            private static final long serialVersionUID = 9140613519878493935L; 
 
            public void actionPerformed(ActionEvent e) 
            { 
                triangulationWindow.reset(); 
            } 
        }); 
 
        randomGenerateButton = new JButton(new AbstractAction( 
                "Randomize Points") 
        { 
            private static final long serialVersionUID = 9140613519878493936L; 
 
            public void actionPerformed(ActionEvent e) 
            { 
                randomizePointsDialog();
            } 
        }); 
         
        loadButton = new JButton(new AbstractAction( 
            "Load") 
        { 
            private static final long serialVersionUID = 9140613519878493937L; 
 
            public void actionPerformed(ActionEvent e) 
            { 
                loadVerticesDialog(); 
            } 
        }); 
         
        saveButton = new JButton(new AbstractAction( 
            "Save") 
        { 
            private static final long serialVersionUID = 9140613519878493938L; 
             
            public void actionPerformed(ActionEvent e) 
            { 
            	saveVerticesDialog();
            } 
        }); 
 
        triangulatersComboBox = new JComboBox(); 
        triangulatersComboBox.setAction(new AbstractAction() 
        { 
            private static final long serialVersionUID = 723646785157461810L; 
 
            public void actionPerformed(ActionEvent e) 
            { 
                activeTriangulater = triangulatersComboBox.getSelectedIndex();
                
                if (triangulaters != null && infoPanel != null)
                	infoPanel.setActiveTriangulator(triangulaters.elementAt(activeTriangulater));
                
                triangulationWindow.processChanges(); 
            } 
        }); 
         
        windowNorth.add(clearButton); 
        windowNorth.add(Box.createRigidArea(new Dimension(10, 10))); 
        windowNorth.add(randomGenerateButton); 
        windowNorth.add(Box.createRigidArea(new Dimension(10, 10))); 
        windowNorth.add(loadButton); 
        windowNorth.add(Box.createRigidArea(new Dimension(10, 10))); 
        windowNorth.add(saveButton); 
        windowNorth.add(Box.createRigidArea(new Dimension(30, 10))); 
        windowNorth.add(new JLabel("Triangulation method: ")); 
        windowNorth.add(Box.createRigidArea(new Dimension(10, 10))); 
        windowNorth.add(triangulatersComboBox); 

        
        getContentPane().add(windowNorth, BorderLayout.NORTH); 
        getContentPane().add(windowCenter, BorderLayout.CENTER); 
         
        randPointsDialog = new RandomizePointsDialog(this);
        saveVertsDialog = new SaveVerticesDialog(this);
        loadVertsDialog = new LoadVerticesDialog(this);
 
        setVisible(true); 
        
        addTriangulator(new Triangulation.ConvexHullEdgeGenerator());
//        addTriangulator(new Triangulation.PolygonTriangulator());
        addTriangulator(new Triangulation.FastLMTTriangulator( 
                new ShortestEdgesMetric())); 
        addTriangulator(new Triangulation.FastLMTTriangulator( 
                new AdjacentBaseToHeightRatioMetric())); 
        addTriangulator(new Triangulation.FastLMTTriangulator( 
                new LongestBaseToHeightRatioMetric())); 
        addTriangulator(new Triangulation.OldLMTTriangulator( 
                new OldShortestEdgesMetric())); 
        
        infoPanel = new ExtraInfoPanel();
        infoPanel.setTriangleDisplay(this.triangulationWindow);
        getContentPane().add(infoPanel, BorderLayout.PAGE_END); 
        
        if (showExtraInfo == false)
        	infoPanel.setVisible(false);
        
        doLayout();
    } 
 
    public void triangulate(Vector<Vertex> vertices) 
    { 
        if (triangulaters.size() > activeTriangulater && vertices.size() > 1) 
        { 
            Vertex[] aVertices = new Vertex[vertices.size()]; 
            vertices.toArray(aVertices); 
            triangulationWindow.showMesh(triangulaters.elementAt( 
                    activeTriangulater).processVertices(aVertices)); 
//            triangulationWindow.setVertices(vertices); 
        } 
        
        if (infoPanel != null)
        	infoPanel.repaint();
    } 
 
    public void addTriangulator(Triangulation.EdgeGenerator t) 
    { 
        triangulaters.add(t); 
        triangulatersComboBox.addItem(t.getName()); 
    } 
 
    public void randomizePointsDialog() 
    {     
        randPointsDialog.setVisible(true); 
    } 
    public void randomizePoints(int numPoints) 
    { 
    	triangulationWindow.spawnRandomPoints(numPoints); 
    }
    
    public void saveVerticesDialog() 
    {     
        saveVertsDialog.showSaveDialog(); 
    } 
    public void saveVertices(String state) 
    { 
    	triangulationWindow.spawnSavePoints(state);
    }
    
    public void loadVerticesDialog() 
    {     
        loadVertsDialog.showLoadDialog(); 
    } 
    public void loadVertices(String state) 
    { 
    	triangulationWindow.spawnLoadPoints(state); 
    }
}
